package com.jh.complicate.rpc.v1.server;

import com.jh.complicate.rpc.v1.api.RPCRequest;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;

/**
 * @author Administrator
 * @projectName newforward
 * @title ProcessorHandler.java
 * @package com.jh.complicate.rpc.v1.server
 * @description RPC 任务处理
 * @date 2019/6/11 22:34
 */
public class ProcessorHandler implements Runnable {

    private Object service;
    private Socket socket;

    public ProcessorHandler(Object service, Socket socket) {
        this.service = service;
        this.socket = socket;
    }

    @Override
    public void run() {
        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;

        try {
            // 获取输入流
            ois = new ObjectInputStream(socket.getInputStream());
            // 获取请求接口信息
            RPCRequest request = (RPCRequest) ois.readObject();

            // 执行反射方法
            Object result = invoke(request);

            // 获取输出流
            oos = new ObjectOutputStream(socket.getOutputStream());
            // 写
            oos.writeObject(result);
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } finally {
            if (null != ois) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != oos) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private Object invoke(RPCRequest request) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 反射调用，参数类型获取
        Object[] args = request.getParameters();
        Class<?>[] types = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            types[i] = args[i].getClass();
        }

        // 反射出class，但是这个类传过来的是接口，不是具体的实现类
        Class<?> clazz = Class.forName(request.getClassName());
        Method method = clazz.getMethod(request.getMethod(), types);

        Object result = method.invoke(service, args);
        System.out.println("调用方法成功");
        return result;
    }
}
